package ixLog

import (
	"encoding/json"
	"fmt"
	"os"
	"time"
)

// DefaultConfig 返回默认配置
func DefaultConfig() *Config {
	hostname, _ := os.Hostname()

	return &Config{
		// 基础配置
		Level:          INFO,
		Format:         TextFormat,
		EnableColor:    true,
		EnableCaller:   true,
		CallerSkip:     DefaultCallerSkip,
		TimeFormat:     DefaultTimeFormat,
		Timezone:       "Local",
		CustomTemplate: "",

		// 输出配置
		Outputs: []OutputConfig{
			{
				Type:   ConsoleTarget,
				Enable: true,
				Writer: os.Stdout,
			},
		},
		EnableAsync:   true,
		BufferSize:    DefaultBufferSize,
		FlushInterval: DefaultFlushInterval,

		// 追踪配置
		EnableTrace: true,
		StackDepth:  DefaultStackDepth,
		SampleRate:  DefaultSampleRate,

		// 全局字段
		GlobalFields: make(map[string]interface{}),
		AppName:      "app",
		Environment:  "development",
		Hostname:     hostname,

		// 安全配置
		EnableSanitize: false,
		SanitizeFields: []string{"password", "token", "secret", "key", "auth"},
		SanitizePatterns: []string{
			`\b\d{11}\b`, // 手机号
			`\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`, // 邮箱
			`\b\d{15}|\d{18}\b`, // 身份证号
		},

		// 钩子配置
		EnableHooks: true,
	}
}

// ConfigOption 配置选项函数类型
type ConfigOption func(*Config)

// WithLevel 设置日志级别
func WithLevel(level LogLevel) ConfigOption {
	return func(c *Config) {
		c.Level = level
	}
}

// WithFormat 设置输出格式
func WithFormat(format OutputFormat) ConfigOption {
	return func(c *Config) {
		c.Format = format
	}
}

// WithColor 设置是否启用颜色
func WithColor(enable bool) ConfigOption {
	return func(c *Config) {
		c.EnableColor = enable
	}
}

// WithCaller 设置是否启用调用者信息
func WithCaller(enable bool) ConfigOption {
	return func(c *Config) {
		c.EnableCaller = enable
	}
}

// WithCallerSkip 设置调用者跳过层数
func WithCallerSkip(skip int) ConfigOption {
	return func(c *Config) {
		c.CallerSkip = skip
	}
}

// WithTimeFormat 设置时间格式
func WithTimeFormat(format string) ConfigOption {
	return func(c *Config) {
		c.TimeFormat = format
	}
}

// WithTimezone 设置时区
func WithTimezone(timezone string) ConfigOption {
	return func(c *Config) {
		c.Timezone = timezone
	}
}

// WithCustomTemplate 设置自定义模板
func WithCustomTemplate(template string) ConfigOption {
	return func(c *Config) {
		c.CustomTemplate = template
	}
}

// WithConsoleOutput 添加控制台输出
func WithConsoleOutput(enable bool) ConfigOption {
	return func(c *Config) {
		// 查找现有的控制台输出配置
		for i, output := range c.Outputs {
			if output.Type == ConsoleTarget {
				c.Outputs[i].Enable = enable
				return
			}
		}

		// 如果没有找到，添加新的控制台输出配置
		if enable {
			c.Outputs = append(c.Outputs, OutputConfig{
				Type:   ConsoleTarget,
				Enable: true,
				Writer: os.Stdout,
			})
		}
	}
}

// WithFileOutput 添加文件输出
func WithFileOutput(filePath string, options ...FileOutputOption) ConfigOption {
	return func(c *Config) {
		output := OutputConfig{
			Type:       FileTarget,
			Enable:     true,
			FilePath:   filePath,
			Rotation:   NoRotation,
			MaxSize:    DefaultMaxSize,
			MaxAge:     DefaultMaxAge,
			MaxBackups: DefaultMaxBackups,
			Compress:   true,
		}

		// 应用文件输出选项
		for _, opt := range options {
			opt(&output)
		}

		c.Outputs = append(c.Outputs, output)
	}
}

// FileOutputOption 文件输出选项函数类型
type FileOutputOption func(*OutputConfig)

// WithRotation 设置轮转策略
func WithRotation(policy RotationPolicy) FileOutputOption {
	return func(o *OutputConfig) {
		o.Rotation = policy
	}
}

// WithMaxSize 设置最大文件大小(MB)
func WithMaxSize(maxSize int64) FileOutputOption {
	return func(o *OutputConfig) {
		o.MaxSize = maxSize
	}
}

// WithMaxAge 设置最大保留天数
func WithMaxAge(maxAge int) FileOutputOption {
	return func(o *OutputConfig) {
		o.MaxAge = maxAge
	}
}

// WithMaxBackups 设置最大备份数量
func WithMaxBackups(maxBackups int) FileOutputOption {
	return func(o *OutputConfig) {
		o.MaxBackups = maxBackups
	}
}

// WithCompress 设置是否压缩
func WithCompress(compress bool) FileOutputOption {
	return func(o *OutputConfig) {
		o.Compress = compress
	}
}

// WithNetworkOutput 添加网络输出
func WithNetworkOutput(network, address string, timeout time.Duration) ConfigOption {
	return func(c *Config) {
		c.Outputs = append(c.Outputs, OutputConfig{
			Type:    NetworkTarget,
			Enable:  true,
			Network: network,
			Address: address,
			Timeout: timeout,
		})
	}
}

// WithAsync 设置是否启用异步输出
func WithAsync(enable bool) ConfigOption {
	return func(c *Config) {
		c.EnableAsync = enable
	}
}

// WithBufferSize 设置缓冲区大小
func WithBufferSize(size int) ConfigOption {
	return func(c *Config) {
		c.BufferSize = size
	}
}

// WithFlushInterval 设置刷新间隔
func WithFlushInterval(interval time.Duration) ConfigOption {
	return func(c *Config) {
		c.FlushInterval = interval
	}
}

// WithTrace 设置追踪配置
func WithTrace(enable bool, stackDepth int, sampleRate float64) ConfigOption {
	return func(c *Config) {
		c.EnableTrace = enable
		c.StackDepth = stackDepth
		c.SampleRate = sampleRate
	}
}

// WithGlobalFields 设置全局字段
func WithGlobalFields(fields map[string]interface{}) ConfigOption {
	return func(c *Config) {
		if c.GlobalFields == nil {
			c.GlobalFields = make(map[string]interface{})
		}
		for k, v := range fields {
			c.GlobalFields[k] = v
		}
	}
}

// WithAppInfo 设置应用信息
func WithAppInfo(appName, environment string) ConfigOption {
	return func(c *Config) {
		c.AppName = appName
		c.Environment = environment
	}
}

// WithSanitize 设置脱敏配置
func WithSanitize(enable bool, fields []string, patterns []string) ConfigOption {
	return func(c *Config) {
		c.EnableSanitize = enable
		if fields != nil {
			c.SanitizeFields = fields
		}
		if patterns != nil {
			c.SanitizePatterns = patterns
		}
	}
}

// WithHooks 设置是否启用钩子
func WithHooks(enable bool) ConfigOption {
	return func(c *Config) {
		c.EnableHooks = enable
	}
}

// NewConfig 创建配置
func NewConfig(options ...ConfigOption) *Config {
	config := DefaultConfig()

	for _, opt := range options {
		opt(config)
	}

	return config
}

// LoadConfigFromFile 从文件加载配置
func LoadConfigFromFile(filePath string) (*Config, error) {
	data, err := os.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %w", err)
	}

	config := DefaultConfig()

	// 根据文件扩展名选择解析方式
	switch {
	case len(filePath) > 5 && filePath[len(filePath)-5:] == ".json":
		err = json.Unmarshal(data, config)
	default:
		return nil, fmt.Errorf("不支持的配置文件格式，仅支持 .json")
	}

	if err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %w", err)
	}

	// 验证配置
	if err := ValidateConfig(config); err != nil {
		return nil, fmt.Errorf("配置验证失败: %w", err)
	}

	return config, nil
}

// LoadConfigFromEnv 从环境变量加载配置
func LoadConfigFromEnv() *Config {
	config := DefaultConfig()

	// 从环境变量读取配置
	if level := os.Getenv("LOG_LEVEL"); level != "" {
		switch level {
		case "TRACE":
			config.Level = TRACE
		case "DEBUG":
			config.Level = DEBUG
		case "INFO":
			config.Level = INFO
		case "WARN":
			config.Level = WARN
		case "ERROR":
			config.Level = ERROR
		case "FATAL":
			config.Level = FATAL
		}
	}

	if format := os.Getenv("LOG_FORMAT"); format != "" {
		switch format {
		case "text":
			config.Format = TextFormat
		case "json":
			config.Format = JSONFormat
		case "custom":
			config.Format = CustomFormat
		}
	}

	if appName := os.Getenv("APP_NAME"); appName != "" {
		config.AppName = appName
	}

	if env := os.Getenv("ENVIRONMENT"); env != "" {
		config.Environment = env
	}

	if filePath := os.Getenv("LOG_FILE"); filePath != "" {
		config.Outputs = append(config.Outputs, OutputConfig{
			Type:       FileTarget,
			Enable:     true,
			FilePath:   filePath,
			Rotation:   SizeRotation,
			MaxSize:    DefaultMaxSize,
			MaxAge:     DefaultMaxAge,
			MaxBackups: DefaultMaxBackups,
			Compress:   true,
		})
	}

	return config
}

// SaveConfigToFile 保存配置到文件
func SaveConfigToFile(config *Config, filePath string) error {
	var data []byte
	var err error

	// 根据文件扩展名选择序列化方式
	switch {
	case len(filePath) > 5 && filePath[len(filePath)-5:] == ".json":
		data, err = json.MarshalIndent(config, "", "  ")
	default:
		return fmt.Errorf("不支持的配置文件格式，仅支持 .json")
	}

	if err != nil {
		return fmt.Errorf("序列化配置失败: %w", err)
	}

	if err := os.WriteFile(filePath, data, 0644); err != nil {
		return fmt.Errorf("写入配置文件失败: %w", err)
	}

	return nil
}

// ValidateConfig 验证配置
func ValidateConfig(config *Config) error {
	if config == nil {
		return fmt.Errorf("配置不能为空")
	}

	// 验证日志级别
	if config.Level < TRACE || config.Level > FATAL {
		return fmt.Errorf("无效的日志级别: %d", config.Level)
	}

	// 验证输出格式
	if config.Format < TextFormat || config.Format > CustomFormat {
		return fmt.Errorf("无效的输出格式: %d", config.Format)
	}

	// 验证时间格式
	if config.TimeFormat == "" {
		return fmt.Errorf("时间格式不能为空")
	}

	// 验证缓冲区大小
	if config.BufferSize <= 0 {
		return fmt.Errorf("缓冲区大小必须大于0")
	}

	// 验证刷新间隔
	if config.FlushInterval <= 0 {
		return fmt.Errorf("刷新间隔必须大于0")
	}

	// 验证调用栈深度
	if config.StackDepth < 0 {
		return fmt.Errorf("调用栈深度不能为负数")
	}

	// 验证采样率
	if config.SampleRate < 0 || config.SampleRate > 1 {
		return fmt.Errorf("采样率必须在0-1之间")
	}

	// 验证输出配置
	if len(config.Outputs) == 0 {
		return fmt.Errorf("至少需要一个输出配置")
	}

	for i, output := range config.Outputs {
		if err := validateOutputConfig(&output); err != nil {
			return fmt.Errorf("输出配置[%d]验证失败: %w", i, err)
		}
	}

	return nil
}

// validateOutputConfig 验证输出配置
func validateOutputConfig(output *OutputConfig) error {
	if output.Type < ConsoleTarget || output.Type > CustomTarget {
		return fmt.Errorf("无效的输出类型: %d", output.Type)
	}

	switch output.Type {
	case FileTarget:
		if output.FilePath == "" {
			return fmt.Errorf("文件输出必须指定文件路径")
		}
		if output.MaxSize <= 0 {
			return fmt.Errorf("最大文件大小必须大于0")
		}
		if output.MaxAge < 0 {
			return fmt.Errorf("最大保留天数不能为负数")
		}
		if output.MaxBackups < 0 {
			return fmt.Errorf("最大备份数量不能为负数")
		}

	case NetworkTarget:
		if output.Network == "" {
			return fmt.Errorf("网络输出必须指定网络类型")
		}
		if output.Address == "" {
			return fmt.Errorf("网络输出必须指定地址")
		}
		if output.Timeout <= 0 {
			return fmt.Errorf("网络超时时间必须大于0")
		}

	case CustomTarget:
		if output.CustomWriter == nil {
			return fmt.Errorf("自定义输出必须指定写入器")
		}
	}

	return nil
}

// Clone 克隆配置
func (c *Config) Clone() *Config {
	clone := *c

	// 深拷贝切片和映射
	clone.Outputs = make([]OutputConfig, len(c.Outputs))
	copy(clone.Outputs, c.Outputs)

	clone.SanitizeFields = make([]string, len(c.SanitizeFields))
	copy(clone.SanitizeFields, c.SanitizeFields)

	clone.SanitizePatterns = make([]string, len(c.SanitizePatterns))
	copy(clone.SanitizePatterns, c.SanitizePatterns)

	clone.GlobalFields = make(map[string]interface{})
	for k, v := range c.GlobalFields {
		clone.GlobalFields[k] = v
	}

	return &clone
}

// String 返回配置的字符串表示
func (c *Config) String() string {
	data, _ := json.MarshalIndent(c, "", "  ")
	return string(data)
}
